#!/bin/bash
###############################################################################
#       脚本名称: log_buffer.sh
#       功能描述: 缓冲区管理模块,实现批量缓冲提高写入性能。
#       作者: 林再来
#       日期: 2025-10-14
#       版本: 1.0
#       功能:
#           1、内存缓冲区管理
#           2、批量刷新策略(按数量、按时间)
#           3、自动刷新和手动刷新
#           4、进程退出前强制刷新
#       依赖(插件/命令):
#           无
###############################################################################

# 防止重复加载
[[ -n "${_LOG_BUFFER_LOADED:-}" ]] && return 0
readonly _LOG_BUFFER_LOADED=1

#-----------------------------------------------------------------------------
# 全局变量
#-----------------------------------------------------------------------------
# 缓冲区数组(每个appender一个缓冲区)
declare -gA _LOG_BUFFER_DATA
# 缓冲区计数器
declare -gA _LOG_BUFFER_COUNT
# 缓冲区配置
declare -gA _LOG_BUFFER_CONFIG
# 最后刷新时间
declare -gA _LOG_BUFFER_LAST_FLUSH

#-----------------------------------------------------------------------------
# 默认配置（参考config模块的做法，先检查是否已定义）
#-----------------------------------------------------------------------------
if [[ -z "${DEFAULT_BUFFER_SIZE:-}" ]]; then
    readonly DEFAULT_BUFFER_SIZE=100        # 默认缓冲100条
fi
if [[ -z "${DEFAULT_FLUSH_INTERVAL:-}" ]]; then
    readonly DEFAULT_FLUSH_INTERVAL=5       # 默认5秒刷新一次
fi

#-----------------------------------------------------------------------------
# 函数: 初始化缓冲区
# 参数: $1 - appender名称
#       $2 - 缓冲区大小(可选,默认100)
#       $3 - 刷新间隔秒数(可选,默认5秒)
# 返回: 0-成功
#-----------------------------------------------------------------------------
function _log_buffer_init() {
    local appender_name="$1"
    local buffer_size="${2:-$DEFAULT_BUFFER_SIZE}"
    local flush_interval="${3:-$DEFAULT_FLUSH_INTERVAL}"
    
    # 初始化缓冲区
    _LOG_BUFFER_DATA["$appender_name"]=""
    _LOG_BUFFER_COUNT["$appender_name"]=0
    _LOG_BUFFER_CONFIG["${appender_name}_size"]="$buffer_size"
    _LOG_BUFFER_CONFIG["${appender_name}_interval"]="$flush_interval"
    _LOG_BUFFER_LAST_FLUSH["$appender_name"]=$(date +%s)
    
    return 0
}

#-----------------------------------------------------------------------------
# 函数: 添加日志到缓冲区
# 参数: $1 - appender名称
#       $2 - 日志内容
# 返回: 0-成功, 1-缓冲区满需要刷新
#-----------------------------------------------------------------------------
function _log_buffer_add() {
    local appender_name="$1"
    local log_content="$2"
    
    # 检查缓冲区是否已初始化
    if [[ -z "${_LOG_BUFFER_COUNT[$appender_name]:-}" ]]; then
        _log_buffer_init "$appender_name"
    fi
    
    # 添加到缓冲区
    if [[ -z "${_LOG_BUFFER_DATA[$appender_name]}" ]]; then
        _LOG_BUFFER_DATA["$appender_name"]="$log_content"
    else
        _LOG_BUFFER_DATA["$appender_name"]+=$'\n'"$log_content"
    fi
    
    # 增加计数
    ((++_LOG_BUFFER_COUNT["$appender_name"]))
    
    # 检查是否需要刷新
    local buffer_size="${_LOG_BUFFER_CONFIG[${appender_name}_size]}"
    local current_count="${_LOG_BUFFER_COUNT[$appender_name]}"
    
    if [[ $current_count -ge $buffer_size ]]; then
        return 1  # 需要刷新
    fi
    
    # 检查时间间隔
    local current_time=$(date +%s)
    local last_flush="${_LOG_BUFFER_LAST_FLUSH[$appender_name]}"
    local flush_interval="${_LOG_BUFFER_CONFIG[${appender_name}_interval]}"
    local elapsed=$((current_time - last_flush))
    
    if [[ $elapsed -ge $flush_interval ]]; then
        return 1  # 需要刷新
    fi
    
    return 0
}

#-----------------------------------------------------------------------------
# 函数: 获取缓冲区内容
# 参数: $1 - appender名称
# 返回: 输出缓冲区的所有内容
#-----------------------------------------------------------------------------
function _log_buffer_get() {
    local appender_name="$1"
    echo "${_LOG_BUFFER_DATA[$appender_name]:-}"
}

#-----------------------------------------------------------------------------
# 函数: 获取缓冲区大小
# 参数: $1 - appender名称
# 返回: 输出缓冲区当前条数
#-----------------------------------------------------------------------------
function _log_buffer_size() {
    local appender_name="$1"
    echo "${_LOG_BUFFER_COUNT[$appender_name]:-0}"
}

#-----------------------------------------------------------------------------
# 函数: 清空缓冲区
# 参数: $1 - appender名称
# 返回: 0-成功
#-----------------------------------------------------------------------------
function _log_buffer_clear() {
    local appender_name="$1"
    
    _LOG_BUFFER_DATA["$appender_name"]=""
    _LOG_BUFFER_COUNT["$appender_name"]=0
    _LOG_BUFFER_LAST_FLUSH["$appender_name"]=$(date +%s)
    
    return 0
}

#-----------------------------------------------------------------------------
# 函数: 刷新缓冲区(清空但返回内容)
# 参数: $1 - appender名称
# 返回: 输出缓冲区内容并清空
#-----------------------------------------------------------------------------
function _log_buffer_flush() {
    local appender_name="$1"
    
    # 获取内容
    local content="${_LOG_BUFFER_DATA[$appender_name]:-}"
    
    # 清空缓冲区
    _log_buffer_clear "$appender_name"
    
    # 返回内容
    echo "$content"
}

#-----------------------------------------------------------------------------
# 函数: 检查是否需要刷新
# 参数: $1 - appender名称
# 返回: 0-需要刷新, 1-不需要
#-----------------------------------------------------------------------------
function _log_buffer_should_flush() {
    local appender_name="$1"
    
    # 检查计数
    local buffer_size="${_LOG_BUFFER_CONFIG[${appender_name}_size]:-$DEFAULT_BUFFER_SIZE}"
    local current_count="${_LOG_BUFFER_COUNT[$appender_name]:-0}"
    
    if [[ $current_count -ge $buffer_size ]]; then
        return 0
    fi
    
    # 检查时间间隔
    local current_time=$(date +%s)
    local last_flush="${_LOG_BUFFER_LAST_FLUSH[$appender_name]:-$current_time}"
    local flush_interval="${_LOG_BUFFER_CONFIG[${appender_name}_interval]:-$DEFAULT_FLUSH_INTERVAL}"
    local elapsed=$((current_time - last_flush))
    
    if [[ $elapsed -ge $flush_interval ]]; then
        return 0
    fi
    
    return 1
}

#-----------------------------------------------------------------------------
# 函数: 刷新所有缓冲区
# 参数: 无
# 返回: 0-成功
#-----------------------------------------------------------------------------
function _log_buffer_flush_all() {
    for appender_name in "${!_LOG_BUFFER_COUNT[@]}"; do
        local count="${_LOG_BUFFER_COUNT[$appender_name]}"
        if [[ $count -gt 0 ]]; then
            # 这里只清空,实际刷新由调用者处理
            _log_buffer_clear "$appender_name"
        fi
    done
    return 0
}

#-----------------------------------------------------------------------------
# 函数: 设置缓冲区配置
# 参数: $1 - appender名称
#       $2 - 配置项(size/interval)
#       $3 - 配置值
# 返回: 0-成功
#-----------------------------------------------------------------------------
function _log_buffer_set_config() {
    local appender_name="$1"
    local config_key="$2"
    local config_value="$3"
    
    _LOG_BUFFER_CONFIG["${appender_name}_${config_key}"]="$config_value"
    return 0
}

#-----------------------------------------------------------------------------
# 函数: 获取缓冲区统计信息
# 参数: $1 - appender名称
# 返回: 输出统计信息
#-----------------------------------------------------------------------------
function _log_buffer_stats() {
    local appender_name="$1"
    
    local count="${_LOG_BUFFER_COUNT[$appender_name]:-0}"
    local size="${_LOG_BUFFER_CONFIG[${appender_name}_size]:-$DEFAULT_BUFFER_SIZE}"
    local interval="${_LOG_BUFFER_CONFIG[${appender_name}_interval]:-$DEFAULT_FLUSH_INTERVAL}"
    local last_flush="${_LOG_BUFFER_LAST_FLUSH[$appender_name]:-0}"
    local current_time=$(date +%s)
    local elapsed=$((current_time - last_flush))
    
    echo "Appender: $appender_name"
    echo "  当前条数: $count"
    echo "  缓冲大小: $size"
    echo "  刷新间隔: ${interval}秒"
    echo "  距上次刷新: ${elapsed}秒"
}

#-----------------------------------------------------------------------------
# 测试函数
#-----------------------------------------------------------------------------
function _log_buffer_test() {
    echo "=== 缓冲区管理模块测试 ==="
    
    echo ""
    echo "1. 初始化缓冲区:"
    _log_buffer_init "test_buffer" 5 10
    echo "  ✓ 缓冲区初始化成功"
    
    echo ""
    echo "2. 添加日志到缓冲区:"
    for i in {1..3}; do
        _log_buffer_add "test_buffer" "[INFO] 测试日志 $i"
        echo "  添加第${i}条,当前大小: $(_log_buffer_size test_buffer)"
    done
    
    echo ""
    echo "3. 查看缓冲区内容:"
    echo "$(_log_buffer_get test_buffer)" | sed 's/^/  /'
    
    echo ""
    echo "4. 继续添加触发刷新:"
    _log_buffer_add "test_buffer" "[INFO] 测试日志 4"
    _log_buffer_add "test_buffer" "[INFO] 测试日志 5"
    
    if _log_buffer_should_flush "test_buffer"; then
        echo "  ✓ 达到刷新条件"
        local content=$(_log_buffer_flush "test_buffer")
        echo "  刷新内容:"
        echo "$content" | sed 's/^/    /'
        echo "  刷新后大小: $(_log_buffer_size test_buffer)"
    fi
    
    echo ""
    echo "5. 缓冲区统计信息:"
    _log_buffer_stats "test_buffer" | sed 's/^/  /'
}

# 如果直接执行此脚本,运行测试
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    _log_buffer_test
fi

